import javax.swing.*;
import java.awt.*;
import java.io.IOException;
import java.net.ServerSocket;
import java.util.ArrayList;

public class Server implements Runnable {
    private final int PORT = 12345;     //监听端口
    private final int MAX_THREADS = 2; //最大可连接
    private JTextArea textArea;     //文本区域
    private JFrame frame;
    private final JFrame PromptFrame = new JFrame("提示");
    private final JLabel nameLabel = new JLabel("联机成功，开始五子棋游戏！！！",SwingConstants.CENTER);

    private final MySQLConn conn = new MySQLConn();     //自定义的数据库连接类

    private final ArrayList<Thread> threads = new ArrayList<>(); //<Thread>列表中每个元素都是线程
    private volatile int connectedClients = 0;

    public Server(JTextArea textArea,JFrame frame)  {
        this.textArea = textArea;
        this.frame = frame;
    }

    public JTextArea getTextArea() {
        return textArea;
    }

    private void closeServiceWindow() {
        frame.setVisible(false);
        // 关闭连接窗口
        // 或者如果是JDialog: connectionDialog.setVisible(false);
    }

    private void openPromptWindow() {
        PromptFrame.setSize(400, 300);
        PromptFrame.setLocationRelativeTo(null);
        PromptFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);   //关闭窗口会结束
        PromptFrame.setLayout(new BorderLayout());      // 设置
        PromptFrame.setResizable(false);  // 禁止窗口调整大小
        PromptFrame.setAlwaysOnTop(true);  // 窗口始终置顶

        nameLabel.setFont(new Font("宋体",Font.PLAIN,15));
        nameLabel.setVisible(true);
        nameLabel.setPreferredSize(new Dimension(100,30));
        PromptFrame.add(nameLabel,BorderLayout.CENTER);

        PromptFrame.setVisible(true);
    }

    // 在 Server 类中添加一个计数器
      // volatile 保证多线程可见性

    // 添加一个同步方法，用于客户端连接成功后调用
    public synchronized void onClientConnected() {
        connectedClients++;
        if (connectedClients == MAX_THREADS) {
            SwingUtilities.invokeLater(() -> {
                closeServiceWindow();
                openPromptWindow();
            });
        }
    }

    public int getconnectedClients() {
        return connectedClients;
    }

    public synchronized void appendTextArea(String str) {   //这些线程在输出的时候能做好布置了（互斥），每个线程是互斥去使用的
        textArea.append(str);
    }

    @Override
    public void run() {
        try (ServerSocket serverSocket = new ServerSocket(PORT)) {  //有滞后，没出去   ；这里也可以实现多客户端连接，但很麻烦每个客户端要很多不同端口号
            conn.connect();

            serverSocket.setSoTimeout(5000);
            // 设置读取超时时间为5秒：当尝试读取客户端数据时，若超过5秒未收到数据，会抛出SocketTimeoutException
            // 设置游戏等待时间超时 5 秒
            appendTextArea("游戏已启动，等待玩家连接...\n");   //在界面上打印出来
            conn.writeLog("游戏已启动，等待玩家连接...\n");

            for (int i = 0; i < MAX_THREADS; i++) {
                ClientHandler clientHandler = new ClientHandler(serverSocket,this);     //this就是server
                Thread thread = new Thread(clientHandler);
                threads.add(thread);    //结束用的
                thread.start();     //只能在for循坏里处理了，实例化在里面的话
                appendTextArea("服务线程" + thread.getName() + "启动\n");

                //认为线程是结束的
                conn.writeLog("服务线程" + thread.getName() + "启动\n");
            }


            for (Thread thread: threads) {
                thread.join();
            }
        }   catch (IOException e) {
            appendTextArea("游戏启动失败:" + e.getMessage() + "\n");
            conn.writeLog("游戏启动失败:" + e.getMessage() + "\n");

        } catch (InterruptedException e) {      //中断异常
            appendTextArea("游戏被中断：" + e.getMessage() + "\n");
            conn.writeLog("游戏被中断：" + e.getMessage() + "\n");
        }finally {
            interruptAllCHThreads();
            appendTextArea("游戏服务结束");
            conn.writeLog("游戏服务结束");
            conn.disconnect();
        }
    }

    private void interruptAllCHThreads() {
        for (Thread thread: threads) {
            thread.interrupt();
            appendTextArea("服务线程" + Thread.currentThread().getName() + "被中断");
            conn.writeLog("服务线程" + Thread.currentThread().getName() + "被中断");
        }
    }
}

